import pandas as pd
import warnings
warnings.filterwarnings('ignore')

df = pd.read_csv('air_data.csv')
#数据检视三板斧
print(df.head())
df.info()
print(df.describe())

#二、数据筛选
#第一步
#将 第一年消费金额 和 第二年 消费金额 都是非空 的数据 筛选出来
data =df[df["SUM_YR_1"].notnull()&df["SUM_YR_2"].notnull()]
#notnull() 非空       0 ： True，Nan： False #数据中 ，，之间 为空 ，python 用Nan 非数字来表示
#isnull() 是空
# 0
#第二步
#基于 上一步的筛选 ，进一步筛选  或者是  第一年消费金额>0,或者 第二年消费金额大于0，或者 （总里程！=0，并且 平均折扣率！=0）
#第一年消费金额>0 的行索引
index1=data["SUM_YR_1"]>0
#第二年消费金额大于0
index2=data["SUM_YR_2"]>0
#总里程！=0，并且 平均折扣率！=0）#将错就错：总里程==0，并且 平均折扣率==0）
index3 = (data["SEG_KM_SUM"]==0) &  (data["avg_discount"]==0)



#特征筛选
data = data[index1|index2|index3]
print(data.shape)
#[ "FFP_DATE" 入会注册时间,
# "LOAD_TIME",上次登陆时间
#  "FLIGHT_COUNT",飞行次数
# "SUM_YR_1",第一年消费总额
# "SUM_YR_2",第二年消费总额
# "SEG_KM_SUM",飞行总里程
# "AVG_INTERVAL" , 平均乘坐飞机的时间间隔（对该乘客而言，正常乘坐飞机的间隔）
# "MAX_INTERVAL", 最大乘坐飞机的时间间隔
# "avg_discount" 平均折扣率
data=data[[ "FFP_DATE", "LOAD_TIME", "FLIGHT_COUNT", "SUM_YR_1", "SUM_YR_2", "SEG_KM_SUM", "AVG_INTERVAL" , "MAX_INTERVAL", "avg_discount"]]

#特征转化
# 对数据进行日期化处理
data["FFP_DATE"]=pd.to_datetime(data["FFP_DATE"])
data["LOAD_TIME"]=pd.to_datetime(data["LOAD_TIME"])

# 处理成员日期时长
data["入会时间长度"]=data["LOAD_TIME"]-data["FFP_DATE"]
# 计算每个用户每公里支付价格
data["平均每公里票价"] =(data["SUM_YR_1"]+data["SUM_YR_2"])/data["SEG_KM_SUM"]
## 计算乘坐航班时间间隔差
data["时间间隔差值"]=data["MAX_INTERVAL"]-data["AVG_INTERVAL"]

#重命名属性名称
data = data.rename(columns={'FLIGHT_COUNT':'飞行次数',"SEG_KM_SUM":'总里程',"avg_discount":'平均折扣率'})
data=data[["入会时间长度", "飞行次数", "平均每公里票价", "总里程", "时间间隔差值", "平均折扣率"]]
#"入会时间"-L
#"时间间隔差值" -R
#"飞行次数"-F
#"平均每公里票价"-M
# "平均折扣率"-C
# "总里程"----重要属性
print(data.head())

#将入会时间转化为天  因为K-means 做的是聚类处理，使用距离进行度量 ，数据形式必须为数字
data['入会时间长度']=data['入会时间长度'].astype('int64')/(24*60*60*10**9)
print(data['入会时间长度'].head())
data.info()

#数据标准化
from sklearn.preprocessing import StandardScaler
ss= StandardScaler()
#雷达图中 对应 每个角度的xticks 是columns_name
columns_name = list(data.columns)
columns_name.append(columns_name[0])
print("columns_name")
print(columns_name)
data=ss.fit_transform(data)
#选择不同的k值 进行聚类
s=[] #误差平方和
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']='SimHei'

for k in range(4,7):
    model = KMeans(n_clusters=k)
    model.fit(data)
    sse = model.inertia_
    s.append(sse)

    #将 每次聚类的聚类中心 取出
    cluster_centers_list=model.cluster_centers_
    #绘制雷达图
    #当 聚类中心 是4，或者5，或者6 某个值时，绘图
    for cluster_center in cluster_centers_list:
        #y
        cluster_center=list(cluster_center)
        print("cluster_center")
        print(cluster_center)
        cluster_center.append(cluster_center[0])
        length = cluster_center
        #x :角度
        angle = np.linspace(0,2*np.pi,6,endpoint=False)
        angle=list(angle)
        angle.append(angle[0])
        # 角度相关的标签 #data是 特征矩阵 数据帧
        ticks = columns_name
        print("angle")
        print(angle)
        print("length")
        print(length)
        plt.polar(angle,length)
        print("ticks")
        print(ticks)
        plt.xticks(angle,ticks)
    #当k值是4或5或6时，将此时的所有聚类中心画到一张图上
    plt.show()





plt.plot(range(4,7),s)
plt.title('肘部法则')
plt.show()


# 六、结论
# 通过观察可知：
#
# 当k取值4时，每个人群包含的信息比较复杂，且特征不明显
#
# 当k取值5时，分析的结果比较合理，分出的五种类型人群都有自己的特点又不相互重复
#
# 当k取值6时，各种人群也都有自己的特点，但是第4簇人群完全在第5簇人群特征中包含了，有点冗余的意思
#
# 综上，当k取值为5时，得到最好的聚类效果，将所有的客户分成5个人群，再进一步分析可以得到以下结论：
#
# 1.第一簇人群，10957人，最大的特点是时间间隔差值最大，分析可能是“季节型客户”，一年中在某个时间段需要多次乘坐飞机进行旅行，其他的时间则出行的不多，这类客户我们需要在保持的前提下，进行一定的发展；
# 2.第二簇人群，14732人，最大的特点就是入会的时间较长，属于老客户按理说平均折扣率应该较高才对，但是观察窗口的平均折扣率较低，而且总里程和总次数都不高，分析可能是流失的客户，需要在争取一下，尽量让他们“回心转意”；
# 3.第三簇人群，22188人，各方面的数据都是比较低的，属于一般或低价值用户
# 4.第四簇人群，8724人，最大的特点就是平均每公里票价和平均折扣率都是最高的，应该是属于乘坐高等舱的商务人员，应该是需要重点发展的对象，另外应该积极采取相关的优惠政策是他们的乘坐次数增加
# 5.第五簇人群，5443人， 总里程和飞行次数都是最多的，而且平均每公里票价也较高，是重点保持对象

#最终选择k=5
model=KMeans(n_clusters=5)
model.fit(data)
#每个样本对应的标签 （簇/类别）
labels = model.labels_

s1=pd.Series(labels)
#对 标签进行频数统计
#每个类别 对应的 样本数量
s2=s1.value_counts()
#1柱状图：统计 各个类别 的 客户数量

#柱状图 横坐标 是 对应的 类，纵坐标是 该类的人数
# s2.plot(kind='bar')
plt.bar(range(0,5),s2)
#添加 每个横坐标 对应的 类别的标签(描述)
ticks=['一般保持客户', '易流失客户', '低价值客户', '重点发展客户', '重点保持客户']
plt.xticks(range(0,5),ticks)
plt.show()

#饼图
plt.pie(s2,labels=ticks,autopct="%2.1f%%") #小数点前最多保留2位，小数点后保留1位，浮点数，后面打印出%
plt.show()

#有间隙的饼图(披萨块之间的距离)
explore=[0.01]*len(ticks)
plt.pie(s2,explore,labels=ticks,autopct="%2.1f%%") #小数点前最多保留2位，小数点后保留1位，浮点数，后面打印出%
plt.show()